package com.joesem.sale.client.network

import com.joesem.sale.client.base.isSuccess
import com.joesem.sale.client.base.toast
import com.joesem.sale.client.db.LoginTable
import com.joesem.sale.client.logic.event.FilterMode
import com.joesem.sale.client.logic.event.EventFilterMultipleMode
import com.joesem.sale.client.network.data.*
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.File


class ApiService private constructor() {
    private val apiService = NetworkTools.apiService
    private val pageLimit = 20

    companion object {
        val service: ApiService by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
            ApiService()
        }
    }

    suspend fun login(account: String, pwd: String) =
        apiService.login(hashMapOf("username" to account, "password" to pwd))
            .isSuccess(successAction = {
                if (it.data?.access_token.isNullOrEmpty()) {
                    throw Throwable("token is empty")
                } else {
                    LoginTable.table.saveToken(account, it.data?.access_token.orEmpty())
                }
            })

    suspend fun workOrderParams(): CallResponse<WorkOrderParamsMode?> {
        return apiService.workOrderFilterParams().isSuccess(successAction = {
            it.data?.let {

            }
        })
    }

    private var workOrderPage = 1
    suspend fun workOrder(
        date_type: String,
        date_start: String,
        date_end: String,
        about_me: String,
        status: String,
        type: String,
        isFirst: Boolean
    ): CallResponse<List<WorkOrderMode?>?> {
        if (isFirst)
            workOrderPage = 1
        return apiService.workOrderList(
            date_type = date_type,
            date_start = date_start,
            date_end = date_end,
            about_me = about_me,
            status = status,
            type = type,
            page = workOrderPage,
            limit = pageLimit
        ).isSuccess(successAction = {
            workOrderPage += 1
        }) {
            if (workOrderPage > 1)
                workOrderPage -= 1
        }
    }

    suspend fun workOrderDetails(id: String) = apiService.workOrderDetails(id)

    private var customerListPage = 1
    suspend fun getCustomerList(
        keyword: String?,
        isFirst: Boolean
    ): CallResponse<List<CustomerListMode?>?> {
        if (isFirst)
            customerListPage = 1
        return apiService.getCustomerList(keyword, customerListPage, pageLimit)
            .isSuccess(successAction = {
                customerListPage += 1
            }, failed = {
                if (customerListPage > 1)
                    customerListPage -= 1
            })
    }
    private var productsListPage = 1
    suspend fun getProductsList(
        customerId: String?,
        isFirst: Boolean
    ): CallResponse<List<ProductMode?>?> {
        if (isFirst)
            productsListPage = 1
        return apiService.getCustomerProductList(customerId, productsListPage, pageLimit)
            .isSuccess(successAction = {
                productsListPage += 1
            }, failed = {
                if (productsListPage > 1)
                    productsListPage -= 1
            })
    }

    suspend fun uploadImg(file: File) = apiService.uploadFileOcr(
        MultipartBody.Part.createFormData(
            "attachment",
            file.name,
            file.readBytes().toRequestBody("image/*".toMediaTypeOrNull())
        )
    )

    suspend fun createWorkOrder(value: HashMap<String, Any?>): CallResponse<OrderCreateMode?> {
        return apiService.createWorkOrder(value)
    }

    suspend fun getArea(parentId: Int?): CallResponse<List<AreaMode?>?> {
        return apiService.area(parentId)
    }

    suspend fun orderStart(id: Int?) = apiService.orderStart(id)

    suspend fun orderAccept(id: Int?) = apiService.orderAccept(id)


    suspend fun orderAllot(id: Int?, values: HashMap<String, Any?>) =
        apiService.orderAllot(id, values)

    private var bomPage = 1
    suspend fun getBomList(
        isFirst: Boolean,
        keyword: String? = null,
        status: Int? = null
    ): CallResponse<Any?> {
        if (isFirst)
            bomPage = 1
        else
            bomPage += 1
        return apiService.getBomList(keyword, status, bomPage, pageLimit)
            .isSuccess(failed = {
                if (bomPage > 1)
                    bomPage -= 1
            })
    }


    suspend fun orderReceipt(id: String?, value: HashMap<String, Any?>) =
        apiService.orderReceipt(id, value)


    private var noticePage = 1
    suspend fun noticeList(isFirst: Boolean, type: String): CallResponse<List<NoticeListMode?>?> {
        if (isFirst) {
            noticePage = 1
        } else {
            noticePage += 1
        }
        return apiService.noticeList(type, noticePage, pageLimit).isSuccess(failed = {
            if (noticePage > 1)
                noticePage -= 1
        }, successAction = {
            if (noticePage > 1 && it.data.isNullOrEmpty()) {
                toast("已加载全部！")
            }
        })
    }

    suspend fun noticeRead(id: Int?) = apiService.noticeMarkRead(id)

    suspend fun eventDetails(id: Int?) = apiService.eventDetails(id)

    suspend fun getDept() = apiService.getDept()

    private var deptUserPage = 1
    suspend fun getDeptUser(id: String?, isFirst: Boolean): CallResponse<List<DeptUserMode?>?> {
        if (isFirst) {
            deptUserPage = 1
        } else {
            deptUserPage += 1
        }
        return apiService.getDeptUser(id, deptUserPage, pageLimit).isSuccess(failed = {
            if (deptUserPage > 1)
                deptUserPage -= 1
        }, successAction = {
            if (deptUserPage > 1 && it.data.isNullOrEmpty()) {
                toast("已加载全部！")
            }
        })
    }

    suspend fun eventAllot(id: Int?, values: HashMap<String, Any?>) =
        apiService.eventAllot(id, values)

    suspend fun eventReturn(id: Int?, values: HashMap<String, Any?>) =
        apiService.eventReturn(id, values)

    private var eventListPage = 1
    suspend fun eventList(
        state: String?,
        params: EventFilterMultipleMode?,
        isFirst: Boolean
    ): CallResponse<List<EventListMode?>?> {
        if (isFirst) {
            eventListPage = 1
        } else {
            eventListPage += 1
        }
        return apiService.eventList(
            state = state,
            type = params?.type?.code,
            about_me = params?.about_me?.code,
            date = params?.date?.code,
            page = eventListPage,
            limit = pageLimit
        ).isSuccess(failed = {
            if (eventListPage > 1)
                eventListPage -= 1
        }, successAction = {
            if (eventListPage > 1 && it.data.isNullOrEmpty()) {
                toast("已加载全部！")
            }
        })
    }


    suspend fun getEventParams() = apiService.getEventParams().isSuccess(successAction = {
        it.data?.apply {

            about_me.addAll(
                mutableSetOf(
                    FilterMode(title = "全部", code = ""),
                    FilterMode(title = "我协助", code = "assist"),
                    FilterMode(title = "我负责", code = "master"),
                    FilterMode(title = "我创建", code = "create"),
                )
            )
            date.addAll(
                mutableSetOf(
                    FilterMode(title = "全部", code = ""),
                    FilterMode(title = "今天", code = "today"),
                    FilterMode(title = "本周内", code = "week"),
                    FilterMode(title = "本月", code = "month"),
                    FilterMode(title = "本年", code = "year"),
                )
            )
        }
    })

    suspend fun noticeCount() = apiService.noticeCount()
    suspend fun orderStatsNum() = apiService.orderStatsNum()
    suspend fun orderRanking() = apiService.orderRanking()
    suspend fun account() = apiService.account()
    suspend fun logout() = apiService.logout()
    suspend fun customerParams() = apiService.customerParams()
    suspend fun userGTCid(v: HashMap<String, String>) = apiService.userGTCid(v)
    suspend fun createCustomer(values: HashMap<String, Any?>) = apiService.createCustomer(values)
    suspend fun createContact(values: HashMap<String, Any?>) =
        apiService.createContact(values).isSuccess(successAction = { it ->
            it.data?.let {
                it.province_name = values["province_name"]?.toString()
                it.city_name = values["city_name"]?.toString()
                it.county_name = values["county_name"]?.toString()
            }
        })
}